#include <iostream>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <unordered_map>
#include <vector>
#include <mutex>
const int PTHREADCOUNT=4;       
int localNum;
std::mutex mtx;
pthread_cond_t cond;
std::unordered_map<pthread_t,int>hash;
#define ERR_EXIT(m)\
do\
{\
    perror(m);\
    exit(EXIT_FAILURE);\
}while(0)
void* pthreadFunc(void* argv){
    pthread_t mytid=pthread_self();
    
    while(1){
        std::lock_guard<std::mutex>lock(mtx);
        // if(localNum<2000){
        (&cond,mtx.native_handle());
            std::cout<<"i am pthread: "<<mytid<<"now localNum="<<++localNum<<std::endl;
            usleep(1000);
            hash[mytid]++;
        // }    
        // else break;
    }
    return  nullptr;
}

int main(){
    std::ios::sync_with_stdio(false);
    pthread_cond_init(&cond,nullptr);
    std::vector<pthread_t>tids(PTHREADCOUNT);
    for (int i = 0; i < PTHREADCOUNT; i++)
    {
       if(pthread_create(&tids[i],nullptr,pthreadFunc,nullptr) != 0)ERR_EXIT("pthread_create");
       hash.emplace(tids[i],0);
    }
    //detached each pthread
    for(auto tid:tids){
        if(pthread_detach(tid) != 0)
            ERR_EXIT("pthread_detach");
    }


    // each 3s evoke one pthread
    for(int i =0;i<PTHREADCOUNT&&localNum<2000;i=PTHREADCOUNT%(i+1)){
        usleep(1);
        pthread_cond_signal(&cond);
    }


    // for(auto tid:tids){
    //     if(pthread_join(tid,nullptr) != 0)
    //         ERR_EXIT("pthread_join");
    // }
    pthread_cond_destroy(&cond);
    //display each pthread using times
    for(auto& [tid,t]:hash){
        std::cout<<tid<<": "<<t<<std::endl;
    }
}